//
//  PhotoBrowserCell.swift
//  weibo
//
//  Created by 张衡 on 15/8/16.
//  Copyright © 2015年 张衡. All rights reserved.
//

/**
 * cell 具有一个 imageURL: NSURL 属性，
 *cell 的层次结构 contentview 中有占满的 scrollview , scrollview 中 有 uiimageview ，
 * 其中scrollview 用自动布局
 * uiimageview用frame布局，涉及长短图，用scrollview 的宽度为基准，使用原图的长宽比，得出图像 size, scrollview 高度 同图像高度进行比较，得出长短图，分别设置出不同类型 uiimageview 的frame
*/
import UIKit
import SDWebImage

protocol PhotoBrowserCellDelegate: NSObjectProtocol {
    // cell 缩放比例
    func photoBrowserCellZoom(scale: CGFloat)
    
    // 结束缩放
    func photoBrowserCellEndZoom()
}

class PhotoBrowserCell: UICollectionViewCell {
    
    // 代理
    weak var photoDelegate: PhotoBrowserCellDelegate?
    
    var imageURL: NSURL? {
        didSet {
            // 显示菊花
            indicator.startAnimating()
            
            
            /// 重设 scrollview (cell 的重用注意点）
            resetScrollView()
            
            // 错误的设置方法，图像下载结束后，没有设置图像大小
            // imageView.sd_setImageWithURL(imageUIL)
            // 用 sdWebImage 不一定能下载到图像
            // 原因：
            // 1. url 错误
            // 2. 超时时长： 15s
            // 提示：函数执行完成后，imageView 就是下载的图像
            
            // 清空图像，解决图像缓存问题,cell 重用
            imageView.image = nil
            
            // 模拟延时  // NSEC_PER_SEC
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0 * NSEC_PER_SEC)), dispatch_get_main_queue()) { () -> Void in
                // 用 sdWebImage 异步加载网络图像 ，如果cell被重用， 之前的图像仍然存在
                self.imageView.sd_setImageWithURL(self.imageURL, completed: { (image, _, _, _) -> Void in
                    
                    self.indicator.stopAnimating()
                    
                    if image == nil {
                        // 应该用一个占位图像代替显示的图像
                        print("下载图像错误")
                        return
                    }
                    // 设置图片位置
                    self.setupImagePosition()
                })
            }
        }
    }
    
    /// 重设 ScrollView 偏移属性
    private func resetScrollView() {
        
        // 重设 imageView 的形变
        imageView.transform = CGAffineTransformIdentity
        
        scrollView.contentInset = UIEdgeInsetsZero
        scrollView.contentOffset = CGPointZero
        scrollView.contentSize = CGSizeZero
    }
    
    // 设置图像位置
    /// 提示：“长短图” 的概念在照片查看器中非常重要
    private func setupImagePosition() {
        let s = self.displaySize(imageView.image!)
        
        // 图像高度比视图高度小，短图
        if s.height < scrollView.bounds.height {
            // 垂直居中
            let y = (scrollView.bounds.height - s.height) * 0.5
            
            // 通过frame 进行布局
            imageView.frame = CGRect(origin: CGPointZero, size: s)
            
            // 设置往中间🐔的间距，保证缩放完成后，同样能够显示完整画面
            scrollView.contentInset = UIEdgeInsets(top: y, left: 0, bottom: y, right: 0)
            
        } else {
            // 长图
            imageView.frame = CGRect(origin: CGPointZero, size: s)
            scrollView.contentSize = s
        }
        
    }
    
    // 计算图像的尺寸，以 scrollview 的宽度为基准
    private func displaySize(image: UIImage) -> CGSize {
        // 图像宽高比
        let scale = image.size.height / image.size.width
        let height = scale * scrollView.bounds.width
        
        return CGSizeMake(scrollView.bounds.width, height)
    }
    
    
    // MARK: - 构造函数u
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupUI()
        
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupUI() {
        // 1. 添加控件
        contentView.addSubview(scrollView)
        scrollView.addSubview(imageView)
        
        
        
        contentView.addSubview(indicator)
        
        // 测试scrollView 布局是否正确
        // scrollView.backgroundColor = UIColor.redColor()
        
//        scrollView.frame = UIScreen.mainScreen().bounds
//        indicator.center = scrollView.center
        
        // 自动布局 - 只需要设置 scrollview 的布局(铺满cell的contentview），imageview 要根据实际图像大小调整位置
        // vlf -- 一次添加多个约束
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        // 制造图片翻页中间的间距20
        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[sv]-20-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["sv": scrollView]))
        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[sv]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["sv": scrollView]))
        
        // 居中显示，用vlf 很难实现，采用另外一种方法 -- 一次添加单个约束
        indicator.translatesAutoresizingMaskIntoConstraints = false
        contentView.addConstraint(NSLayoutConstraint(item: indicator, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: contentView, attribute: NSLayoutAttribute.CenterX, multiplier: 1.0, constant: 0))
        contentView.addConstraint(NSLayoutConstraint(item: indicator, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: contentView, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0))
        
        // 设置控件
        prepareScrollView()
    }
    
    /// 准备 scrollview
    private func prepareScrollView() {
        scrollView.delegate = self
        
        // 最大，最小缩放比例
        scrollView.minimumZoomScale = 0.5
        scrollView.maximumZoomScale = 2.0
    }
   
    
    // 懒加载控件
    private lazy var scrollView = UIScrollView()
    lazy var imageView = UIImageView()
    // 菊花
    private lazy var indicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.White)
    
    
}


extension PhotoBrowserCell: UIScrollViewDelegate {
    // 告诉 scrollview 要缩放的控件
    func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
        return imageView
    }
    
    /// 在缩放完成后，会被调用一次
    func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView?, atScale scale: CGFloat) {
        // 重新计算间距
        // scrollview 是通过 transform 改变 view 的缩放，view的 bound 本身没有变化，frame会变化
        var offsetX = (scrollView.bounds.width - view!.frame.width) * 0.5
        // 如果边距小于0，需要修正
        offsetX = offsetX < 0 ? 0 : offsetX
        
        var offsetY = (scrollView.bounds.height - view!.frame.height) * 0.5
        offsetY = offsetY < 0 ? 0 : offsetY
        
        scrollView.contentInset = UIEdgeInsets(top: offsetY, left: offsetX, bottom: 0, right: 0)
        
        // 通知代理缩放结束
        photoDelegate?.photoBrowserCellEndZoom()
    }
    
    
    /// 只要缩放就会调用
    /**
    transform
    a,d     缩放比例
    tx, ty  位移
    a,b,c,d 共同决定旋转
    */
    func scrollViewDidZoom(scrollView: UIScrollView) {
        // print(imageView.transform)
        photoDelegate?.photoBrowserCellZoom(imageView.transform.a)
    }
    
}
